package org.daymr.puzzle.entity;

import java.nio.FloatBuffer;

import org.daymr.puzzle.tools.BufferUtils;
import org.daymr.puzzle.tools.MatrixUtils;
import org.daymr.puzzle.tools.ShaderUtils;
import org.daymr.puzzle.view.GameView;

import android.opengl.GLES20;

/**
 * 拼图框架
 * @author Ben
 * @date 2014年12月20日 下午9:41:48
 */
public class Desk {
	/**自定义渲染管线程序id */
	int mProgram;
	/**总变换矩阵引用*/
	int muMVPMatrixHandle;
	/**顶点位置属性引用id*/
	int maPositionHandle;
	/**顶点颜色属性引用id */
	int maColorHandle;
	
	/**顶点着色器代码脚本*/
	String mVertexShader;
	/**片元着色器代码脚本*/
	String mFragmentShader;
	
	/**顶点坐标数据缓冲*/
	FloatBuffer mVertexBuffer;
	/**顶点颜色数据缓冲*/
	FloatBuffer mColorBuffer;
	
	/**顶点个数*/
	int mCount=0;
	
	/**框架边长*/
	public static final float DESK_WIDTH = 0.94f;
	public static final float FACTOR = 2f;
	
	public Desk(GameView gv){
		//初始化顶点数据
		initVertexData();
		//初始化着色器
		initShader(gv);
	}
	
	/**
	 * 初始化顶点数据
	 */
	private void initVertexData(){
		//顶点数组
		float[] mVertex = new float[]{
			//前面xy
			-DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//0
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//1
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			
			-DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//0
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//3
			//后面
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//1
			DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//2
			
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0
			DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//2
			DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//3
			
			//上面xz
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0  
			-DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//1 
			DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//2 
			
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//2 
			DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//3
			
			//下面
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//0  
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//1 
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2 
			
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2 
			DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//3
			
			//左面yz
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//1
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			
			-DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			-DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			-DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//3
			
			//右面
			DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			DESK_WIDTH,-DESK_WIDTH/FACTOR,-DESK_WIDTH,//1
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			
			DESK_WIDTH,DESK_WIDTH/FACTOR,-DESK_WIDTH,//0 
			DESK_WIDTH,-DESK_WIDTH/FACTOR,DESK_WIDTH,//2
			DESK_WIDTH,DESK_WIDTH/FACTOR,DESK_WIDTH,//3
			
		};
		//顶点个数
		mCount = mVertex.length/3;
		//顶点缓存
		mVertexBuffer = BufferUtils.getFloatBuffer(mVertex.length*4);
		//在缓冲区内写入数据
		mVertexBuffer.put(mVertex);
		//设置缓冲区的读取位置
		mVertexBuffer.position(0);
		
		//顶点对应的颜色数组
		float[] mColors = new float[]{//r,g,b,a
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				1,0,0,1,
				
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				0,1,0,1,
				
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				0,0,1,1,
				
		};
		mColorBuffer = BufferUtils.getFloatBuffer(mColors.length*4);
		mColorBuffer.put(mColors);
		mColorBuffer.position(0);
	}

	/**
	 * 创建并初始化着色器
	 * @param gv
	 */
	private void initShader(GameView gv){
		//读取顶点着色器代码脚本
		mVertexShader = ShaderUtils.loadFromAssetsFile("desk_vertex.sh", gv.getResources());
		//读取片元着色器代码脚本
		mFragmentShader = ShaderUtils.loadFromAssetsFile("desk_frag.sh", gv.getResources());
		
		//创建着色器程序
		mProgram = ShaderUtils.createProgram(mVertexShader, mFragmentShader);
		
		//获取总变换矩阵引用
		muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
		//获取顶点位置属性引用
		maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
		//获取顶点颜色属性引用
		maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
	}
	
	/**
	 * 绘画
	 */
	public void draw(){
		//使用某套着色器程序
		GLES20.glUseProgram(mProgram);
		//将最终变换矩阵传入着色器程序
		GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, 
				MatrixUtils.getFinalMatrix(), 0);
		//将顶点数据传入着色器程序
		GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
				false, 3*4, mVertexBuffer);
		//将颜色数据传入着色器程序
		GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT,
				false, 4*4, mColorBuffer);
		//允许顶点位置数据数组
		GLES20.glEnableVertexAttribArray(maPositionHandle);
		GLES20.glEnableVertexAttribArray(maColorHandle);
		
		//绘画
		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mCount);
	}
	
}
